(function (angular) {
  'use strict';
  angular.module('fs.keyDown', ['fs.storage']).factory('keyDownService', ['$filter', 'storageService', function ($filter, storageService) {
    //=================================================
    //      On key down                             ===
    //=================================================
    //the formatManager should get from back.
    var formatInfo = storageService.getFormatInfo() || {};
    var decimalSeparator = formatInfo.decimalSeparator || '.';
    var FORMAT_MANAGER = {
      decimalSeparator: decimalSeparator
    };

		/**
		 * Coder can type back space, delete, home and end etc.
		 * @return boolean. when key which is being pressed is one of the following keys, return true.
		 */
    function baseKeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      if (evt.ctrlKey) {
        return (keyCode == 67     // ^C
          || keyCode == 86     // ^V
          || keyCode == 88);   // ^X
      } else {
        return (keyCode == 8     // back space
          || keyCode == 46    // delete
          || keyCode == 35    // home
          || keyCode == 36    // end
          || keyCode == 37    // <-
          || keyCode == 38    // cursor up
          || keyCode == 39    // ->
          || keyCode == 40    // cursor down
          || keyCode == 9);   // tab

      }
    }

		/**
		 * Coder can enter.
		 * @return boolean. when key which pressed is enter, return true.
		 */
    function enterKeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      return (keyCode == 13);     // enter
    }

		/**
		 * type dot.
		 * @return boolean. when key which pressed is dot, return true.
		 */
    function dotKeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      return (keyCode == 110                                 // '.'
        || (!evt.shiftKey && keyCode == 190));  // '.' on standard 102 keyboard   
    }

		/**
		 * type decimal separator 
		 * @return boolean. when key which pressed is decimal separator, return true.
		 */
    function decimalSeparatorKeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      var mark;
      if (evt.shiftKey) {
        var shiftKey = {
          '188': "<", '190': ">", '191': "?",
          '48': ")", '49': "!", '50': "@",
          '51': "#", '52': "$", '53': "%",
          '54': "^", '55': "&", '56': "*",
          '57': "(", '189': "_", '187': "+",
          '192': "~", '219': "{", '221': "}",
          '186': ":", '222': "\"", '173': "_"
        }
        mark = shiftKey[keyCode];
      } else {
        var normalKey = {
          '188': ",", '110': FORMAT_MANAGER.decimalSeparator, '190': ".",//110 is in number keybord
          '32': " ", '189': "-", '187': "=",
          '49': "`", '219': "[", '221': "]",
          '186': ";", '222': "'", '173': "_"
        }
        mark = normalKey[keyCode];
      }
      if (keyCode == 110) {
        (evt.srcElement || evt.target).value = (evt.srcElement || evt.target).value + FORMAT_MANAGER.decimalSeparator;
        evt.returnValue = false;
        if (evt.preventDefault) {
          evt.preventDefault();
        }
      }
      return (FORMAT_MANAGER.decimalSeparator == mark);
    }

		/**
		 * type letters.
		 * @param 
		 * @return boolean
		 */
    function letterKeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      var isValidKey = baseKeyDown(e);
      if (isValidKey) {
        return isValidKey;
      }
      return (keyCode >= 65 && keyCode <= 96);    // a - z;A - Z
    }

		/**
		 * type number.
		 * @return boolean
		 */
    function numKeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      var isValidKey = baseKeyDown(e);
      if (isValidKey) {
        return isValidKey;
      }
      return (!evt.shiftKey && keyCode >= 48 && keyCode <= 57)  // 0 - 9
        || (keyCode >= 96 && keyCode <= 105);   // 0 - 9 on standard 102 Keyboard 
    }

		/**
		 * type ID includes letters, numbers, dash and underscore.
		 * 0 - 9; a - z; A - Z; -; _;
		 * 
		 * @param 
		 * @return boolean
		 */
    function idKeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      var isValidKey = baseKeyDown(e);
      if (isValidKey) {
        return isValidKey;
      }
      isValidKey = (letterKeyDown(e)) || (numKeyDown(e));    // 0 - 9; a - z; A - Z
      if (isValidKey) {
        return isValidKey;
      }
      return (keyCode == 109     // '-' on standard 102 keyboard
        || keyCode == 173	     // '-' or '_' in firefox broswer
        || keyCode == 189);    // '-' or '_' in other broswer
    }

		/**
		 * type ID includes numbers, letters and underscore.
		 * 0 - 9; a - z; A - Z; _;
		 * 
		 * @param 
		 * @return boolean
		 */
    function id2KeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      var isValidKey = baseKeyDown(e);
      if (isValidKey) {
        return isValidKey;
      }
      isValidKey = (letterKeyDown(e)) || (numKeyDown(e));    // 0 - 9; a - z; A - Z
      if (isValidKey) {
        return isValidKey;
      }
      return (evt.shiftKey && keyCode == 173		 // '_' in firefox broswer
        || evt.shiftKey && keyCode == 189);     // '_' in other broswer
    }

		/**
		 * type ID includes numbers, letters and dash.
		 * 0 - 9; a - z; A - Z; ,; -;
		 * 
		 * @param 
		 * @return boolean
		 */
    function id3KeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      var isValidKey = baseKeyDown(e);
      if (isValidKey) {
        return isValidKey;
      }
      isValidKey = (letterKeyDown(e)) || (numKeyDown(e));    // 0 - 9; a - z; A - Z
      if (isValidKey) {
        return isValidKey;
      }
      return (keyCode == 109     // '-' on standard 102 keyboard
        || (!evt.shiftKey && keyCode == 173)   // only '-' in firefox broswer
        || (!evt.shiftKey && keyCode == 189)   // only '-' in other broswer
        || keyCode == 188);  // ','
    }

		/**
		 * type ID includes numbers, letters, dash, underscore, dot andt at.
		 * 0 - 9; a - z; A - Z; -; _; .; @;
		 * 
		 * @param 
		 * @return boolean
		 */
    function id4KeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      var isValidKey = baseKeyDown(e);
      if (isValidKey) {
        return isValidKey;
      }
      isValidKey = (idKeyDown(e)) || (dotKeyDown(e));    // 0 - 9; a - z; A - Z; -; _; .;
      if (isValidKey) {
        return isValidKey;
      }
      return (evt.shiftKey && keyCode == 50);    // only '-' 
    }

		/**
		 * type ID includes numbers and letters.
		 * 0 - 9; a - z; A - Z;
		 * 
		 * @param 
		 * @return boolean
		 */
    function id5KeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      var isValidKey = baseKeyDown(e);
      if (isValidKey) {
        return isValidKey;
      }
      return (letterKeyDown(e)) || (numKeyDown(e));    // 0 - 9; a - z; A - Z
    }

		/**
		 * type ID includes numbers, letters, dash, underscore and space.
		 * 0 - 9; a - z; A - Z; -; _; ' ';
		 * 
		 * @param 
		 * @return boolean
		 */
    function id6KeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      var isValidKey = baseKeyDown(e);
      if (isValidKey) {
        return isValidKey;
      }
      return ((keyCode == 32) || idKeyDown(e));    // 0 - 9; a - z; A - Z; -; _; ' ';
    }

		/**
		 * type class includes letters and dot.
		 * a - z; A - Z; .;
		 * 
		 * @param 
		 * @return boolean
		 */
    function classpathKeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      var isValidKey = baseKeyDown(e);
      if (isValidKey) {
        return isValidKey;
      }
      return (letterKeyDown(e) || dotKeyDown(e));    // a - z; A - Z; .;
    }

		/**
		 * type float number.
		 * @param value
		 * @return
		 */
    function floatKeyDown(e, value) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      var isValidKey = baseKeyDown(e);
      if (isValidKey) {
        return isValidKey;
      }
      isValidKey = numKeyDown(evt); // for number
      if (value && value.indexOf(FORMAT_MANAGER.decimalSeparator) != -1) {
        //if value is float
        return isValidKey;
      } else {
        //if value is integer, U can type decimal separator.
        return (isValidKey || (decimalSeparatorKeyDown(evt)));
      }
    }
    function minusKeyDown(e) {
      var evt = window.event || e;
      var keyCode = evt.which ? evt.which : evt.keyCode;
      return (keyCode == 109     // '-' on standard 102 keyboard
        || (!evt.shiftKey && keyCode == 173)   // only '-' in firefox broswer
        || (!evt.shiftKey && keyCode == 189)); // '-' or '_' in other broswer	
    }
    return {
      numKeyDown: numKeyDown,
      idKeyDown: idKeyDown,
      id2KeyDown: id2KeyDown,
      id3KeyDown: id3KeyDown,
      id4KeyDown: id4KeyDown,
      id5KeyDown: id5KeyDown,
      id6KeyDown: id6KeyDown,
      classpathKeyDown: classpathKeyDown,
      floatKeyDown: floatKeyDown,
      minusKeyDown: minusKeyDown
    };
  }]);
})(angular);
